package main

import (
	"fmt"
	"sync"
)

// 测试go 语言 单例模式

/*
	饿汉式单例：在定义instance时直接实例化，private static Singleton instance = new(Singleton)
	懒汉式单例：在getInstance方法中进行实例化
*/

// 饿汉式
type singleton struct {
	cnt int
}

var Instance = new(singleton)

func (s *singleton) Add() int {
	s.cnt++
	return s.cnt
}

//懒汉式

var (
	instance *singleton
	mutex    sync.Mutex
)

func getInstance() *singleton {
	mutex.Lock()
	if instance == nil {
		instance = new(singleton)
	}
	mutex.Unlock()

	return instance
}

func getInstance2() *singleton {
	// 比getInstance 快
	if instance == nil {
		mutex.Lock()
		if instance == nil {
			instance = new(singleton)
		}
		mutex.Unlock()
	}

	return instance
}

func getInstance3() *singleton {
	// 标准做法
	var once sync.Once
	once.Do(func() {
		instance = new(singleton)
	})

	return instance
}

func main() {
	fmt.Println("test0:")
	fmt.Println(Instance.Add())

	fmt.Println("test1:")
	s1 := getInstance()
	fmt.Println(s1.Add())

	fmt.Println("test2:")
	s2 := getInstance2()
	fmt.Println(s2.Add())

	fmt.Println("test3:")
	s3 := getInstance3()
	fmt.Println(s3.Add())
}
